﻿#include "BezierInterpolator.h"
#include "lang/Exception.h"
#include "lang/StringFormat.hpp"
#include <vector>
using namespace yzrilyzr_array;
using namespace yzrilyzr_util;
using namespace yzrilyzr_lang;
namespace yzrilyzr_interpolator{
	BezierInterpolator::~BezierInterpolator(){}
	u_normal_01 BezierInterpolator::y(u_normal_01 t){
		double sum=0;
		for(u_index i=0;i < points->length;i++){
			double p=(*points)[i];
			double tt=(pow(t, i) * pow(1 - t, points->length - i - 1));
			double c=(*coe)[i];
			sum+=p * tt * c;
		}
		return sum;
	}
	BezierInterpolator::BezierInterpolator(std::shared_ptr<yzrilyzr_array::DoubleArray> pts){
		this->pts=pts;
		points=std::make_shared<DoubleArray>(pts->length + 2);
		for(u_index i=0;i < pts->length;i++){
			(*points)[i + 1]=(*pts)[i];
		}
		(*points)[0]=0.0;
		(*points)[points->length - 1]=1.0;
		u_index rows=points->length;
		if(rows < 2) throw Exception("Points < 2");
		std::vector<double> coe1;
		std::vector<double> temp;
		coe1.push_back(1.0);
		coe1.push_back(1.0);
		for(u_index r=0;r < rows - 2;r++){
			for(u_index i=0;i < coe1.size() - 1;i++){
				double sum=coe1[i] + coe1[i + 1];
				temp.push_back(sum);
			}
			temp.insert(temp.begin(), 1.0);
			temp.push_back(1.0);
			coe1.clear();
			for(double tt:temp)coe1.push_back(tt);
			temp.clear();
		}
		coe=std::make_shared<DoubleArray>((int32_t)coe1.size());
		for(u_index i=0;i < coe1.size();i++){
			(*coe)[i]=coe1[i];
		}
	}
	String BezierInterpolator::toString() const{
		return StringFormat::object2string("BezierInterpolator", pts);
	}
}